package com.wjc.train.member.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wjc.train.common.enums.BusinessEnum;
import com.wjc.train.common.enums.LogicEnum;
import com.wjc.train.common.enums.SmsExpireEnum;
import com.wjc.train.common.exception.BusinessException;
import com.wjc.train.common.exception.BusinessExceptionCode;
import com.wjc.train.common.untils.CopyUtil;
import com.wjc.train.common.untils.JwtUtil;
import com.wjc.train.common.untils.LocalDateUtil;
import com.wjc.train.member.entity.Member;
import com.wjc.train.member.entity.SmsRecord;
import com.wjc.train.member.repository.MemberRepository;
import com.wjc.train.member.repository.SmsRecordRepository;
import com.wjc.train.member.req.MemberLoginReq;
import com.wjc.train.member.req.MemberRegisterReq;
import com.wjc.train.member.req.MemberSendCodeReq;
import com.wjc.train.member.resp.MemberLoginResp;
import com.wjc.train.member.service.IMemberService;
import com.wjc.train.member.service.ISmsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;

/**
 * @author Guessed
 */
@Service
@Slf4j
public class MemberServiceImpl implements IMemberService {

    @Resource
    private MemberRepository memberRepository;

    @Resource
    private SmsRecordRepository smsRecordRepository;

    @Resource
    private ISmsService smsService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean register(List<MemberRegisterReq> memberList) {
        List<String> collect
                = memberList.stream().map(MemberRegisterReq::getMobile).toList();
        long count = memberRepository.lambdaQuery().in(Member::getMobile,collect).count();
        if(count > 0){
            throw new BusinessException(BusinessExceptionCode.USER_MOBILE_EXIST);
        }
        List<Member> members = CopyUtil.copyList(memberList, Member.class);
        memberRepository.saveBatch(members);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MemberLoginResp login(MemberLoginReq memberLoinReq){
        //校验手机号是否注册过
        Member dBmember = memberRepository.getBaseMapper().selectOne(new QueryWrapper<Member>()
                .eq("mobile", memberLoinReq.getMobile()));
        //如果手机号不存在，则报错
        if(ObjectUtil.isEmpty(dBmember)){
           throw new BusinessException(BusinessExceptionCode.USER_MOBILE_NOT_EXIST);
        }
        //校验短信验证码
        SmsRecord smsRecordDb = smsRecordRepository.getBaseMapper().selectOne(new QueryWrapper<SmsRecord>()
                .eq("mobile", memberLoinReq.getMobile())
                .eq("code", memberLoinReq.getCode())
                .eq("is_deleted", LogicEnum.NOT_DELETED.getCode())
                .isNull("use_time")
                .ge("expire_time", new Date()));

        if (ObjectUtil.isEmpty(smsRecordDb)){
            throw new BusinessException(BusinessExceptionCode.MEMBER_MOBILE_CODE_ERROR);
        }
        //设置使用时间,及删除状态
        smsRecordDb.setUseTime(new Date());
        smsRecordDb.setIsDeleted(LogicEnum.DELETED.getCode());
        smsRecordRepository.saveOrUpdate(smsRecordDb);

        MemberLoginResp memberLoginResp = CopyUtil.copy(dBmember, MemberLoginResp.class);
        String token = JwtUtil.createToken(memberLoginResp.getId(), memberLoginResp.getMobile());
        memberLoginResp.setToken(token);
        return memberLoginResp;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sendCode(MemberSendCodeReq memberSendCodeReq){

        String mobile = memberSendCodeReq.getMobile();
        //校验手机号是否注册过
        Long count =
                memberRepository.lambdaQuery().eq(Member::getMobile, mobile).count();

        //如果手机号不存在，则插入记录
        if(count < 1){
            log.info("新增手机号: {}",mobile);
            Member copy = CopyUtil.copy(memberSendCodeReq, Member.class);
            memberRepository.saveOrUpdate(copy);
        }
        //生成验证码,4位
        String codeKey = RandomUtil.randomNumbers(4);
        log.info("生成短信验证码: {}",codeKey);

        //存短信记录表
        //设置日期
        LocalDateTime localTime = LocalDateTime.now();
        LocalDateTime plus = localTime.plus(SmsExpireEnum.FIVE_MINUTES.getExpire(), ChronoUnit.MINUTES);
        Date sendTime = LocalDateUtil.localDateTimeToDate(localTime);
        Date expireTime = LocalDateUtil.localDateTimeToDate(plus);

        SmsRecord smsRecord = new SmsRecord();
        smsRecord.setMobile(mobile);
        smsRecord.setSendTime(sendTime);
        smsRecord.setExpireTime(expireTime);
        smsRecord.setCode(codeKey);
        smsRecord.setBizType(BusinessEnum.MEMBER_REGISTER_LOGIN.getCode());
        smsRecordRepository.saveOrUpdate(smsRecord);

        //对接短信通道，发送短信
        smsService.sendCode(mobile,codeKey);
    }

}
